package com.gzq.common_core.base;

import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;

import androidx.annotation.ColorRes;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

import com.google.gson.Gson;
import com.gzq.common_core.base.config.GlobalConfig;
import com.gzq.common_core.quality.LeakCanaryUtil;
import com.gzq.common_core.session.SessionManager;
import com.gzq.common_core.utils.KVUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.ServiceLoader;

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;

public final class App extends Application {
    private static Application application;
    private ServiceLoader<AppLifecycle> serviceLoader;
    private ArrayList<AppLifecycle> appLifecycles = new ArrayList<>();
    private static ServiceLoader<GlobalConfig> globalServiceLoader;
    private static GlobalModel.Builder globalModelBuilder;
    private static GlobalModel globalModel;
    private ActivityLifecycleCallbacks activityLifecycleCallbacks;
    private static Gson gson;
    private static Retrofit retrofit;
    private static OkHttpClient okHttpClient;

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        //Timber必须尽早初始化
        ObjectFactory.instance().initTimber();
        //全局配置获取
        initGlobalConfig();
        //Application生命周期分发
        handleService();
        if (!appLifecycles.isEmpty()) {
            for (AppLifecycle app : appLifecycles) {
                app.attachBaseContext(this, base);
            }
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        application = this;
        initLibs();
        if (!appLifecycles.isEmpty()) {
            for (AppLifecycle app : appLifecycles) {
                app.onCreate(this);
            }
        }
        if (activityLifecycleCallbacks == null) {
            activityLifecycleCallbacks = new com.gzq.common_core.base.ActivityLifecycleCallbacks();
        }
        registerActivityLifecycleCallbacks(activityLifecycleCallbacks);
        SessionManager.instance().init();
    }


    @Override
    public void onTerminate() {
        super.onTerminate();
        if (activityLifecycleCallbacks != null) {
            unregisterActivityLifecycleCallbacks(activityLifecycleCallbacks);
        }
        ObjectFactory.instance().clear();
        if (!appLifecycles.isEmpty()) {
            for (AppLifecycle app : appLifecycles) {
                app.onTerminate(this);
            }
        }
    }

    private void initLibs() {
        //Toast初始化
        ObjectFactory.instance().initToast(getGlobalModel());
        //初始化屏幕适配器
        ObjectFactory.instance().initAutoSize(getGlobalModel());
        //初始化LeakCanary
        LeakCanaryUtil.instance().init(this);
        //初始化KVUtil
        KVUtils.init(this);
        //用户信息管理器
        ObjectFactory.instance().initSessionManager(getGlobalModel());
        //崩溃拦截配置
        ObjectFactory.instance().initCrashManager(getGlobalModel());
    }

    private void handleService() {
        serviceLoader = ServiceLoader.load(AppLifecycle.class);
        if (serviceLoader != null) {
            for (AppLifecycle life : serviceLoader) {
                appLifecycles.add(life);
            }
        }
        //按priority数字从小到大排序
        Collections.sort(appLifecycles, (o1, o2) -> o1.priority() - o2.priority());
    }

    @SuppressLint("RestrictedApi")
    private void initGlobalConfig() {
        globalServiceLoader = ServiceLoader.load(GlobalConfig.class);
        if (!globalServiceLoader.iterator().hasNext()) {
            throw new NullPointerException("Must implements GlobalConfig at least one and use AutoService");
        }
        globalServiceLoader.iterator().next().applyOptions(this,
                globalModelBuilder = GlobalModel.builder());
    }

    private static GlobalModel getGlobalModel() {
        if (globalModel == null) globalModel = globalModelBuilder.build();
        return globalModel;
    }

    public static Application getApp() {
        return application;
    }

    public static Gson getGson() {
        if (gson == null) {
            gson = ObjectFactory.instance().getGson(getGlobalModel());
        }
        return gson;
    }

    public static OkHttpClient getOkHttpClient() {
        if (okHttpClient == null) {
            okHttpClient = ObjectFactory.instance().getOkHttpClient(getGlobalModel());
        }
        return okHttpClient;
    }

    public static <T> T getRetrofit(Class<T> serviceClazz) {
        if (retrofit == null) {
            retrofit = ObjectFactory.instance().getRetrofit(getGlobalModel());
        }
        return retrofit.create(serviceClazz);
    }

    /**
     * 为了解决在fragment中使用{@link androidx.fragment.app.Fragment#getString(int)}
     * 偶尔会报java.lang.IllegalStateException-->Fragment xxxxx{xxx} not attached to a context的错误
     *
     * @param id 字符串资源id
     * @return
     */
    public static String getSafeString(@StringRes int id) {
        return getApp().getResources().getString(id);
    }

    public static String getSafeString(@StringRes int id, Object... args) {
        return String.format(getSafeString(id), args);
    }
    /**
     * 为了解决在fragment中使用{@link Fragment#getContext()} getContext().getColor(int color)
     * 偶尔会报java.lang.IllegalStateException-->Fragment xxxxx{xxx} not attached to a context的错误
     *
     * @param id 颜色资源id
     * @return
     */
    public static int getSafeColor(@ColorRes int id) {
        return ContextCompat.getColor(getApp(), id);
    }
}
